package com.sky.service.impl;

import com.sky.dto.MinioProperties;
import com.sky.minio.MinioConfiguration;
import com.sky.service.FileService;
import io.minio.BucketExistsArgs;
import io.minio.MakeBucketArgs;
import io.minio.MinioClient;
import io.minio.PutObjectArgs;
import io.minio.SetBucketPolicyArgs;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

@Slf4j
@Service
public class FileServiceImpl implements FileService {

    @Autowired
    private MinioProperties properties;

    @Autowired
    private MinioConfiguration minioConfig; // 统一通过配置类获取客户端

    public String upload(MultipartFile file) {
        // 1. 校验文件是否为空
        if (file.isEmpty()) {
            throw new RuntimeException("上传文件不能为空");
        }

        try {
            // 2. 获取MinIO客户端（统一实例，避免多客户端混乱）
            MinioClient minioClient = minioConfig.minioClient();
            String bucketName = properties.getBucketName(); // 从配置获取Bucket名，统一使用

            // 3. 检查Bucket是否存在，不存在则创建
            boolean bucketExists = minioClient.bucketExists(
                    BucketExistsArgs.builder().bucket(bucketName).build()
            );

            if (!bucketExists) {
                // 创建Bucket
                minioClient.makeBucket(
                        MakeBucketArgs.builder().bucket(bucketName).build()
                );
                log.info("Bucket不存在，已自动创建：{}", bucketName);

                // 4. 动态设置Bucket访问权限（使用实际Bucket名）
                String policy = String.format("""
                    {
                      "Statement": [
                        {
                          "Action": "s3:GetObject",
                          "Effect": "Allow",
                          "Principal": "*",
                          "Resource": "arn:aws:s3:::%s/*"
                        }
                      ],
                      "Version": "2012-10-17"
                    }""", bucketName); // 替换为实际Bucket名

                minioClient.setBucketPolicy(
                        SetBucketPolicyArgs.builder()
                                .bucket(bucketName)
                                .config(policy)
                                .build()
                );
                log.info("已为Bucket设置访问权限：{}", bucketName);
            }

            // 5. 构建文件存储路径（日期目录+UUID+原始文件名，避免重名）
            String dateDir = new SimpleDateFormat("yyyyMMdd").format(new Date());
            String originalFilename = file.getOriginalFilename();
            // 处理可能的空文件名（避免NPE）
            if (originalFilename == null || originalFilename.isEmpty()) {
                originalFilename = "unknown-file";
            }
            String filename = dateDir + "/" + UUID.randomUUID() + "-" + originalFilename;

            // 6. 执行文件上传（无论Bucket是否新建，均执行上传）
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(filename)
                            .stream(file.getInputStream(), file.getSize(), -1)
                            .contentType(file.getContentType()) // 保留文件原始类型
                            .build()
            );

            log.info("文件上传成功，存储路径：{}", filename);

            // 7. 构建并返回文件访问URL
            return String.format("%s/%s/%s", properties.getEndpoint(), bucketName, filename);

        } catch (Exception e) {
            log.error("文件上传失败", e);
            throw new RuntimeException("文件上传失败：" + e.getMessage()); // 补充业务错误信息
        }
    }
}
